package edu.ynu.se.xiecheng.achitectureclass.project.service;

import edu.ynu.se.xiecheng.achitectureclass.project.dao.CameraDAO;
import edu.ynu.se.xiecheng.achitectureclass.project.dao.CameraTokenDAO;
import edu.ynu.se.xiecheng.achitectureclass.project.po.entity.CameraData;
import edu.ynu.se.xiecheng.achitectureclass.project.po.entity.Token;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Service
public class CameraService {

    @Autowired
    private CameraDAO cameraDAO;

    @Autowired
    private CameraTokenDAO cameraTokenDAO;

    @Autowired
    private RestTemplate restTemplate;

    // 抓拍摄像头照片的URL
    private static final String CAPTURE_URL = "https://open.ys7.com/api/lapp/device/capture";

    /**
     * 抓拍摄像头照片并存储到数据库
     *
     * @param deviceSerial 摄像头设备序列号
     * @param quality      视频清晰度
     * @return 存储的CameraData实体
     */
    public CameraData captureAndSavePhoto(String deviceSerial, int quality) {
        try {
            // 获取最新的camera token
            Optional<Token> cameraTokenOpt = cameraTokenDAO.findTopByTypeAndIsDeletedOrderByIdDesc("camera", 0);
            if (!cameraTokenOpt.isPresent()) {
                throw new RuntimeException("No camera token found");
            }
            String accessToken = cameraTokenOpt.get().getToken();

            // 抓拍摄像头照片
            String imageUrl = capturePhoto(accessToken, deviceSerial, quality);
            if (imageUrl == null) {
                throw new RuntimeException("Failed to capture photo: API returned null");
            }

            // 检查并删除已有的CameraData
            List<CameraData> existingData = cameraDAO.findByIsDeleted(0);
            if (!existingData.isEmpty()) {
                cameraDAO.deleteAll(existingData);
            }

            // 将图片URL和设备序列号存储到CameraData实体中
            CameraData cameraData = new CameraData();
            cameraData.setAddress(imageUrl);
            cameraData.setSerialId(deviceSerial);
            cameraData.setTimestamp(LocalDateTime.now());

            // 保存到数据库
            return cameraDAO.save(cameraData);
        } catch (Exception e) {
            throw new RuntimeException("Failed to capture and save photo: " + e.getMessage(), e);
        }
    }

    /**
     * 抓拍摄像头照片
     *
     * @param accessToken  访问token
     * @param deviceSerial 摄像头设备序列号
     * @param quality      视频清晰度
     * @return 抓拍照片的URL
     */
    private String capturePhoto(String accessToken, String deviceSerial, int quality) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        // 使用 MultiValueMap 而不是 HashMap
        MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
        requestBody.add("accessToken", accessToken);
        requestBody.add("deviceSerial", deviceSerial);
        requestBody.add("channelNo", "1");
        requestBody.add("quality", String.valueOf(quality));

        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(requestBody, headers);

        // 打印请求参数
        System.out.println("Request Body: " + requestBody);

        try {
            ResponseEntity<Map> response = restTemplate.postForEntity(CAPTURE_URL, requestEntity, Map.class);

            // 打印响应结果
            System.out.println("Response Status: " + response.getStatusCode());
            System.out.println("Response Body: " + response.getBody());

            if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
                Map<String, Object> responseBody = response.getBody();

                // 检查 code 是否为 "200"
                if (!"200".equals(responseBody.get("code"))) {
                    throw new RuntimeException("API returned error: " + responseBody.get("msg"));
                }

                // 获取 data 字段
                Map<String, Object> data = (Map<String, Object>) responseBody.get("data");
                if (data != null && data.containsKey("picUrl")) {
                    return (String) data.get("picUrl");
                } else {
                    throw new RuntimeException("API response does not contain picUrl: " + responseBody);
                }
            } else {
                throw new RuntimeException("API request failed with status: " + response.getStatusCode());
            }
        } catch (Exception e) {
            throw new RuntimeException("Failed to call capture API: " + e.getMessage(), e);
        }
    }

    /**
     * 根据serialId删除数据
     *
     * @param serialId 摄像头设备序列号
     */
    public void deleteBySerialId(String serialId) {
        List<CameraData> cameraDataList = cameraDAO.findByIsDeleted(0);
        for (CameraData cameraData : cameraDataList) {
            if (cameraData.getSerialId().equals(serialId)) {
                cameraDAO.delete(cameraData);
            }
        }
    }

    /**
     * 查询所有数据
     *
     * @return 所有CameraData实体
     */
    public List<CameraData> findAll() {
        return cameraDAO.findByIsDeleted(0);
    }

    /**
     * 手动导入图片数据
     *
     * @param deviceSerial 摄像头设备序列号
     * @param imageUrl     图片的URL
     * @return 存储的CameraData实体
     */
    public CameraData importPhoto(String deviceSerial, String imageUrl) {
        // 创建 CameraData 实体
        CameraData cameraData = new CameraData();
        cameraData.setAddress(imageUrl); // 图片的 URL
        cameraData.setSerialId(deviceSerial); // 设备序列号
        cameraData.setTimestamp(LocalDateTime.now()); // 当前时间戳

        // 保存到数据库
        return cameraDAO.save(cameraData);
    }

    /**
     * 查询最新的图片数据
     *
     * @return 最新的CameraData实体
     */
    public CameraData getLatestPhoto() {
        List<CameraData> cameraDataList = cameraDAO.findByIsDeleted(0);
        if (cameraDataList.isEmpty()) {
            throw new RuntimeException("No photo data found");
        }
        // 按时间戳排序，返回最新的数据
        return cameraDataList.stream()
                .max(Comparator.comparing(CameraData::getTimestamp))
                .orElseThrow(() -> new RuntimeException("No photo data found"));
    }
}